package com.yonyou.crm.csns.im.service;

import java.util.HashMap;
import java.util.Map;

import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springside.modules.nosql.redis.JedisTemplate;

import com.alibaba.fastjson.JSON;
import com.yonyou.crm.common.biz.service.BaseBizServiceImpl;
import com.yonyou.crm.common.exception.CrmMessageException;
import com.yonyou.crm.common.http.client.CrmHttpClient;
import com.yonyou.crm.common.http.client.CrmResponse;
import com.yonyou.crm.common.rest.constant.AppCodeConstant;
import com.yonyou.crm.common.rest.constant.HttpCodeConstant;
import com.yonyou.crm.common.rest.constant.PCCodeConstant;
import com.yonyou.crm.csns.im.constant.ImConstant;
import com.yonyou.crm.csns.im.entity.ImVO;
import com.yonyou.crm.csns.im.param.ImParam;
import com.yonyou.crm.csns.im.param.ImPubAvatarInfoFactory;

@Service
public class ImBizServiceImpl extends BaseBizServiceImpl<ImVO> {
	
	private final static String ImBaseDir = "https://im.yyuap.com/";
	private final static String AppTokenPrefix = "IMAppToken:";
	
	@Autowired
	private JedisTemplate jedisTemplate;
	
	@Value("${imrest.sendmessageurl}")
	private String sendmessageUrl;
	
	/**
	 * im的apptoken有效期为24小时
	 * 为保持数据同步，本地有效期设置为23小时
	 */
	private final static int ExpireSeconds = 23*60*60;
	@SuppressWarnings("unchecked")
	public Map<String, Object> getImInfo(Long id) {
		return (Map<String, Object>)dao.selectOne(ImVO.class, "getImInfo", id);
	}
	/**
	 * {
     *   "from": "zongtf.udn.yonyou",
     *   "to": ["user1", "user2", "user3"],
     *   "content": "{\"content\": \"这里是消息内容\" }",
     *   "extend": "im.yyuap.com"
     *  }
	 * @param paramObj
	 * 根据该格式进行组装，将其发送至IM消息
	 * @throws CrmMessageException 
	 */
	@SuppressWarnings("unchecked")
	public CrmResponse SendImMessage(ImParam param) throws CrmMessageException{
		String djType = param.getObjType();
		if(djType == null){
			throw new CrmMessageException(AppCodeConstant.ServerError ,"单据类型为空");
		}
		String messageType = param.getMessageType();
		if(messageType == null){
			throw new CrmMessageException(AppCodeConstant.ServerError ,"公众号类型为空");
		}
		String[] users = param.getUsers();
		if(users == null || users.length == 0){
			throw new CrmMessageException(AppCodeConstant.ServerError ,"消息接收者为空");
		}
		Long creatUserId = param.getCreatUserId();
		if(creatUserId == null ){
			throw new CrmMessageException(AppCodeConstant.ServerError ,"提交人id为空");
		}
		String objId = param.getObjId();
		if(objId == null){
			throw new CrmMessageException(AppCodeConstant.ServerError ,"对象id为空");
		}
//		String chartType = "pub_account_"+messageType;
		
		//获取chartType之后，向IM发送请求，创建公共号
		
		JSONObject paramObj = new JSONObject();
		Map<String, Object> imMap = this.getImInfo(creatUserId);
		String eptId = (String) imMap.get(ImConstant.EptId);
		String appId = (String) imMap.get(ImConstant.AppId);
		paramObj.put("from", messageType+"."+appId+"."+eptId);
		   
		String url = sendmessageUrl+"?token="+this.getAppToken(imMap);
		paramObj.put("to", param.getUsers());
		String content = param.getContent();
		JSONObject obj = new JSONObject();
		obj.put("content", content);
		paramObj.put("content", JSON.toJSONString(obj));
		
		@SuppressWarnings("rawtypes")
		Map map = new HashMap();
		map.put("objtype", djType);
		map.put("objid", objId);
		//扩展参数根据公众号类型获取对应的url
		map.put("pubavatar", ImPubAvatarInfoFactory.getInstance().getInfo(messageType).getUrl());
		
		paramObj.put("extend", JSONObject.fromObject(map));
		CrmResponse cResp = CrmHttpClient.post(url, paramObj);
		if (cResp.getCode() != HttpCodeConstant.OK) {
			throw new CrmMessageException("服务器连接异常");
		}
		return cResp;
	}
	
	/**
	 * 获得应用token字符串
	 * @param imMap
	 * @return
	 * @throws CrmMessageException
	 */
	private String getAppToken(Map<String, Object> imMap) throws CrmMessageException {

		String tokenKey = AppTokenPrefix + imMap.get("tenantId");
		
		//从redis中获取
		String appToken = jedisTemplate.get(tokenKey);
		if (StringUtils.isNotBlank(appToken)) {
			return appToken;
		}

		//从im远程获取
		CrmResponse cResp = sendAppTokenRequest(imMap);
		if (cResp.getCode() != HttpCodeConstant.OK) {
			throw new CrmMessageException(cResp.getData());
		}
		
		JSONObject atObj = JSONObject.fromObject(cResp.getData());
		String token = "";
		if (atObj != null && atObj.containsKey("token")) {
			token =  (String) atObj.get("token");
			//存储到redis，过期时间23小时
			jedisTemplate.setnxex(tokenKey, token, ExpireSeconds);
		}

		return token;
	}
	/**
	 * 向IM发送获取应用token请求
	 * @param imMap
	 * @return
	 * @throws CrmMessageException
	 */
	private CrmResponse sendAppTokenRequest(Map<String, Object> imMap) throws CrmMessageException {
		
		if (imMap == null || imMap.size() == 0) {
			throw new CrmMessageException(PCCodeConstant.ServerError, "获取IM认证信息失败");
		}

		String eptId = (String) imMap.get(ImConstant.EptId);
		String appId = (String) imMap.get(ImConstant.AppId);
		String url = ImBaseDir + "sysadmin/rest/"+ eptId +"/"+ appId +"/token";
				
		JSONObject paramObj = new JSONObject();
		paramObj.put(ImConstant.ClientId, imMap.get(ImConstant.ClientId));
		paramObj.put(ImConstant.ClientSecret, imMap.get(ImConstant.ClientSecret));
				
		return CrmHttpClient.post(url, paramObj);
	}
	public String getSendmessageUrl() {
		return sendmessageUrl;
	}
	public void setSendmessageUrl(String sendmessageUrl) {
		this.sendmessageUrl = sendmessageUrl;
	}

}
